//
// Created on 2025/5/28.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef DRAWINGAPI_H
#define DRAWINGAPI_H

#include "config/SkUserConfig.h"
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_error_code.h>
#include <native_drawing/drawing_font.h>
#include <native_drawing/drawing_shader_effect.h>
#include <native_drawing/drawing_types.h>
#include <native_drawing/drawing_path.h>
#include <native_drawing/drawing_image_filter.h>
#include <native_drawing/drawing_text_declaration.h>
#include <native_drawing/drawing_font_collection.h>
#include <multimedia/image_framework/image/image_packer_native.h>

typedef enum {
    DRAWING_PATH_DASH_STYLE_TRANSLATE_TEMP,
    DRAWING_PATH_DASH_STYLE_ROTATE_TEMP,
    DRAWING_PATH_DASH_STYLE_MORPH_TEMP,
} OH_Drawing_PathDashStyle_Temp;

#define DRAWING_API_LIST(X)                                                                                            \
    X(                                                                                                                 \
        OH_Drawing_CanvasDrawRecordCmdNesting,                                                                         \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_INFO, "No OH_Drawing_CanvasDrawRecordCmdNesting support");                          \
            return OH_Drawing_CanvasDrawRecordCmd(canvas, recordCmd);                                                  \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Canvas *canvas, OH_Drawing_RecordCmd *recordCmd)                              \
    X(                                                                                                                 \
        OH_Drawing_FontMeasureTextWithBrushOrPen,                                                                      \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN, "No OH_Drawing_FontMeasureTextWithBrushOrPen support");                       \
            return OH_Drawing_FontMeasureText(font, text, byteLength, encoding, bounds, textWidth);                    \
        },                                                                                                             \
        OH_Drawing_ErrorCode, const OH_Drawing_Font *font, const void *text, size_t byteLength,                        \
        OH_Drawing_TextEncoding encoding, const OH_Drawing_Brush *brush, const OH_Drawing_Pen *pen,                    \
        OH_Drawing_Rect *bounds, float *textWidth)                                                                     \
    X(                                                                                                                 \
        OH_Drawing_FontGetWidthsBounds,                                                                                \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN, "No OH_Drawing_FontGetWidthsBounds support");                                 \
            OH_Drawing_FontGetWidths(font, glyphs, count, widths);                                                     \
            return OH_DRAWING_SUCCESS;                                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, const OH_Drawing_Font *font, const uint16_t *glyphs, int count,                          \
        const OH_Drawing_Brush *brush, const OH_Drawing_Pen *pen, float *widths, OH_Drawing_Array *bounds)             \
    X(                                                                                                                 \
        OH_Drawing_FontGetPos,                                                                                         \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_FontGetPos support");                                         \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, const OH_Drawing_Font *font, const uint16_t *glyphs, int count,                          \
        const OH_Drawing_Point *origin, OH_Drawing_Point2D *points)                                                    \
    X(                                                                                                                 \
        OH_Drawing_FontGetSpacing,                                                                                     \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_FontGetSpacing support");                                     \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, const OH_Drawing_Font *font, float *spacing)                                             \
    X(                                                                                                                 \
        OH_Drawing_RectCreateArray,                                                                                    \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_RectCreateArray support");                                    \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_Array *, size_t size)                                                                               \
    X(                                                                                                                 \
        OH_Drawing_RectGetArrayElement,                                                                                \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_RectGetArrayElement support");                                \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Array *rectArray, size_t index, OH_Drawing_Rect **rect)                       \
    X(                                                                                                                 \
        OH_Drawing_RectDestroyArray,                                                                                   \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_RectDestroyArray support");                                   \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Array *rectArray)                                                             \
    X(                                                                                                                 \
        OH_Drawing_ShaderEffectCreateSweepGradientWithLocalMatrix,                                                     \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN,                                                                               \
                               "No OH_Drawing_ShaderEffectCreateSweepGradientWithLocalMatrix(API20) support");         \
            return OH_Drawing_ShaderEffectCreateSweepGradient(centerPt, colors, pos, size, tileMode);                  \
        },                                                                                                             \
        OH_Drawing_ShaderEffect *, const OH_Drawing_Point *centerPt, const uint32_t *colors, const float *pos,         \
        uint32_t size, OH_Drawing_TileMode tileMode, const OH_Drawing_Matrix *matrix)                                  \
    X(                                                                                                                 \
        OH_Drawing_ImageFilterCreateOffset,                                                                            \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_ImageFilterCreateOffset(API20) support");                     \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_ImageFilter *, float x, float y, OH_Drawing_ImageFilter *imageFilter)                               \
    X(                                                                                                                 \
        OH_Drawing_CreateComposePathEffect,                                                                            \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_CreateComposePathEffect(API18) support");                     \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_PathEffect *, OH_Drawing_PathEffect *outer, OH_Drawing_PathEffect *inner)                           \
    X(                                                                                                                 \
        OH_Drawing_CreateCornerPathEffect,                                                                             \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_CreateCornerPathEffect(API18) support");                      \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_PathEffect *, float radius)                                                                         \
    X(                                                                                                                 \
        OH_Drawing_CreatePathDashEffect,                                                                               \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_CreatePathDashEffect(API18) support");                        \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_PathEffect *, OH_Drawing_Path *path, float advance, float phase,                                    \
        OH_Drawing_PathDashStyle_Temp type)                                                                            \
    X(                                                                                                                 \
        OH_Drawing_FontGetPathForGlyph,                                                                                \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_FontGetPathForGlyph(API18) support");                         \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, const OH_Drawing_Font *font, uint16_t glyph, OH_Drawing_Path *path)                      \
    X(                                                                                                                 \
        OH_Drawing_PathIsEmpty,                                                                                        \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_PathIsEmpty(API20) support");                                 \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Path *path, bool *isEmpty)                                                    \
    X(                                                                                                                 \
        OH_Drawing_PathIsRect,                                                                                         \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_PathIsRect(API20) support");                                  \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Path *path, OH_Drawing_Rect *rect, bool *isRect)                              \
    X(                                                                                                                 \
        OH_Drawing_PathGetFillType,                                                                                    \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_PathGetFillType(API20) support");                             \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Path *path, OH_Drawing_PathFillType *pathFillType)                            \
    X(                                                                                                                 \
        OH_Drawing_PathGetSegment,                                                                                     \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_PathGetSegment(API18) support");                              \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Path *path, bool forceClosed, float start, float stop, bool startWithMoveTo,  \
        OH_Drawing_Path *dst, bool *result)                                                                            \
    X(                                                                                                                 \
        OH_Drawing_CanvasDrawArcWithCenter,                                                                            \
        {                                                                                                              \
            if (useCenter) {                                                                                           \
                RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_CanvasDrawArcWithCenter(API18) support");                 \
            }                                                                                                          \
            OH_Drawing_CanvasDrawArc(canvas, rect, startAngle, sweepAngle);                                            \
            return OH_DRAWING_SUCCESS;                                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Canvas *canvas, const OH_Drawing_Rect *rect, float startAngle,                \
        float sweepAngle, bool useCenter)                                                                              \
    X(                                                                                                                 \
        OH_Drawing_CanvasDrawNestedRoundRect,                                                                          \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_CanvasDrawNestedRoundRect(API18) support");                   \
            return OH_DRAWING_ERROR_INVALID_PARAMETER;                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Canvas *canvas, const OH_Drawing_RoundRect *outer,                            \
        const OH_Drawing_RoundRect *inner)                                                                             \
    X(                                                                                                                 \
        OH_Drawing_CanvasDrawPixelMapRectConstraint,                                                                   \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN, "No OH_Drawing_CanvasDrawPixelMapRectConstraint(API20) support");             \
            OH_Drawing_CanvasDrawPixelMapRect(canvas, pixelMap, src, dst, samplingOptions);                            \
            return OH_DRAWING_SUCCESS;                                                                                 \
        },                                                                                                             \
        OH_Drawing_ErrorCode, OH_Drawing_Canvas *canvas, OH_Drawing_PixelMap *pixelMap, const OH_Drawing_Rect *src,    \
        const OH_Drawing_Rect *dst, const OH_Drawing_SamplingOptions *samplingOptions,                                 \
        OH_Drawing_SrcRectConstraint constraint)                                                                       \
    X(                                                                                                                 \
        OH_Drawing_ImageFilterCreateBlurWithCrop,                                                                      \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN, "No OH_Drawing_ImageFilterCreateBlurWithCrop(API20) support");                \
            return OH_Drawing_ImageFilterCreateBlur(sigmaX, sigmaY, tileMode, input);                                  \
        },                                                                                                             \
        OH_Drawing_ImageFilter *, float sigmaX, float sigmaY, OH_Drawing_TileMode tileMode,                            \
        OH_Drawing_ImageFilter *input, const OH_Drawing_Rect *rect)                                                    \
    X(                                                                                                                 \
        OH_Drawing_ShaderEffectCreatePixelMapShader,                                                                   \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_Drawing_ShaderEffectCreatePixelMapShader(API20) support");            \
            return nullptr;                                                                                            \
        },                                                                                                             \
        OH_Drawing_ShaderEffect *, OH_Drawing_PixelMap *pixelMap, OH_Drawing_TileMode tileX,                           \
        OH_Drawing_TileMode tileY, const OH_Drawing_SamplingOptions *samplingOptions, const OH_Drawing_Matrix *matrix) \
    X(                                                                                                                 \
        OH_ImagePackerNative_GetSupportedFormats,                                                                      \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_ImagePackerNative_GetSupportedFormats(API20) support");               \
            return IMAGE_BAD_PARAMETER;                                                                                \
        },                                                                                                             \
        Image_ErrorCode, Image_MimeType **supportedFormats, size_t *length)                                            \
    X(                                                                                                                 \
        OH_PixelmapNative_AccessPixels,                                                                                \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_PixelmapNative_AccessPixels(API15) support");                         \
            if (addr) {                                                                                                \
                *addr = nullptr;                                                                                       \
            }                                                                                                          \
            return IMAGE_BAD_PARAMETER;                                                                                \
        },                                                                                                             \
        Image_ErrorCode, OH_PixelmapNative *pixelmap, void **addr)                                                     \
    X(                                                                                                                 \
        OH_PixelmapNative_UnaccessPixels,                                                                              \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_ERROR, "No OH_PixelmapNative_UnaccessPixels(API15) support");                       \
            return IMAGE_BAD_PARAMETER;                                                                                \
        },                                                                                                             \
        Image_ErrorCode, OH_PixelmapNative *pixelmap)                                                                  \
    X(                                                                                                                 \
        OH_Drawing_GetFontCollectionGlobalInstance,                                                                    \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_WARN, "No OH_Drawing_GetFontCollectionGlobalInstance(API14) support");              \
            return OH_Drawing_CreateSharedFontCollection();                                                            \
        },                                                                                                             \
        OH_Drawing_FontCollection *)                                                                                   \
    X(                                                                                                                 \
        OH_ImageSourceNative_CreatePixelmapUsingAllocator,                                                             \
        {                                                                                                              \
            RENDER_API_MISSING(LOG_INFO, "No OH_ImageSourceNative_CreatePixelmapUsingAllocator(API15) support");       \
            return OH_ImageSourceNative_CreatePixelmap(source, options, pixelmap);                                     \
        },                                                                                                             \
        Image_ErrorCode, OH_ImageSourceNative *source, OH_DecodingOptions *options, IMAGE_ALLOCATOR_TYPE allocator,    \
        OH_PixelmapNative **pixelmap)


class OHDrawingAPI {
public:
    explicit OHDrawingAPI();
    ~OHDrawingAPI();

#define DRAWING_SYMBOL_DECLARATION(name, default_code, ret, ...)                                                       \
    typedef ret (*name##Fun)(__VA_ARGS__);                                                                             \
    static name##Fun name;                                                                                             \
    static bool support_##name;
    DRAWING_API_LIST(DRAWING_SYMBOL_DECLARATION);
#undef DRAWING_SYMBOL_DECLARATION

private:
    void loadAllSymblos() {
#define LOAD_DRAWING_SYMBOL(find_name, ...)                                                                            \
    do {                                                                                                               \
        auto find_name##temp = loadSymbol<find_name##Fun>(#find_name);                                                 \
        if (find_name##temp) {                                                                                         \
            find_name = find_name##temp;                                                                               \
            support_##find_name = true;                                                                                \
        }                                                                                                              \
    } while (0);
        DRAWING_API_LIST(LOAD_DRAWING_SYMBOL);
#undef LOAD_DRAWING_SYMBOL
    }
    template <typename T> T loadSymbol(const char *symbolName);
    static constexpr int fHandleCnt = 3;
    void *fHandle[fHandleCnt];
};

#endif // DRAWINGAPI_H
